From 6c206153a35a7dbafbac4ab0b8d2c2314ceded7a Mon Sep 17 00:00:00 2001 From: justbur Date: Sun, 26 Jul 2015 09:03:16 -0400 Subject: [PATCH] C-h for paging is awesome --- README.org | 55 +++++++++++++++++++++++++++++------ which-key.el | 81 +++++++++++++++++++++++++++++++++++----------------- 2 files changed, 102 insertions(+), 34 deletions(-) diff --git a/README.org b/README.org index 9b0faaa95a7..c38d0f5c7c3 100644 --- a/README.org +++ b/README.org @@ -1,5 +1,20 @@ * which-key [[http://melpa.org/#/which-key][http://melpa.org/packages/which-key-badge.svg]] +** What's new +*** Paging +- Paging is now turned on by default, using any prefix plus =C-h= (this doesn't + affect key sequences that start with =C-h= and will not override any key + sequences that end will =C-h=). See the [[#paging][Paging Section]] for more details and + for other options on using and/or disabling paging. +- This makes which-key function as a replacement for the default behavior of + pressing =C-h= after a prefix which shows the key bindings for any prefix. It + is better though, because it saves the prefix that you just entered. So =C-x + C-h C-h C-x= will popup the which-key buffer for the prefix =C-x= change the + page twice and then execute the command bound to =C-x C-x=. +- =C-h= will also now popup the which-key buffer to the first page if it is + pressed before =which-key-idle-delay= takes effect. This means you can set a + long idle delay if you like and just use =C-h= when you want to see + =which-key=. ** Introduction =which-key= is a minor mode for Emacs that displays the keybindings following your currently entered incomplete command (a prefix) in a popup. For example, after enabling the minor mode @@ -25,6 +40,8 @@ Many of these have been implemented and are described below. ** Table of Contents :TOC@4: - [[#which-key-][which-key ]] + - [[#whats-new][What's new]] + - [[#paging][Paging]] - [[#introduction][Introduction]] - [[#install][Install]] - [[#melpa][MELPA]] @@ -45,6 +62,8 @@ Many of these have been implemented and are described below. - [[#key-and-description-replacement][Key and Description replacement]] - [[#sorting][Sorting]] - [[#paging][Paging]] + - [[#method-1-default-using-c-h-or-help-char][Method 1 (default): Using C-h (or =help-char=)]] + - [[#method-2-bind-your-own-keys][Method 2: Bind your own keys]] - [[#other-options][Other Options]] - [[#more-examples][More Examples]] - [[#nice-display-with-split-frame][Nice Display with Split Frame]] @@ -292,14 +311,34 @@ sorting completely) is =which-key-description-order=, which orders by the key's description based on the usual ordering of strings after applying =downcase=. *** Paging -This is a new feature and may have bugs, so it is disabled by default. There are -at least several prefixes that have many keys bound to them, like =C-x=. -which-key displays as many keys as it can given your settings, but for these -prefixes this may not be enough. The paging feature gives you the ability to -bind a key to the function =which-key-show-next-page= which will cycle through -the pages without changing the key sequence you were in the middle of typing. -Essentially, all you need to do to enable this for a prefix like =C-x= is the -following which will bind == to the command. + +There are at least several prefixes that have many keys bound to them, like +=C-x=. which-key displays as many keys as it can given your settings, but for +these prefixes this may not be enough. The paging feature gives you the ability +to bind a key to the function =which-key-show-next-page= which will cycle +through the pages without changing the key sequence you were in the middle of +typing. There are two slightly different ways of doing this. + +**** Method 1 (default): Using C-h (or =help-char=) +This is the easiest way, and is turned on by default. Use +#+BEGIN_SRC emacs-lisp +(setq which-key-use-C-h-for-paging nil) +#+END_SRC +to disable the behavior (this will only take effect after toggling +which-key-mode if it is already enabled). =C-h= can be used with any prefix to +switch pages when there are multiple pages of keys. This changes the default +behavior of emacs which is to show a list of keybindings that apply to a prefix. +For example, if you were to type =C-x C-h= you would get a list of commands that +follow =C-x=. This uses which-key instead to show those keys, and unlike the +emacs default saves the incomplete prefix that you just entered so that the next +keystroke can complete the command. As a bonus you can type =C-x C-h= and the +which-key buffer will pop up immediately (i.e., before =which-key-idle-delay= +kicks in). + +**** Method 2: Bind your own keys + +Essentially, all you need to do for a prefix like =C-x= is the following which +will bind == to the relevant command. #+BEGIN_SRC emacs-lisp (define-key which-key-mode-map (kbd "C-x ") 'which-key-show-next-page) diff --git a/which-key.el b/which-key.el index a7a7823e510..5291b7bdd3d 100644 --- a/which-key.el +++ b/which-key.el @@ -200,6 +200,13 @@ prefixes in `which-key-paging-prefixes'" :group 'which-key :type 'string) +(defcustom which-key-use-C-h-for-paging t + "Use C-h for paging if non-nil. Normally C-h after a prefix + calls `describe-prefix-bindings'. This changes that command to + a which-key paging command when which-key-mode is active." + :group 'which-key + :type 'boolean) + ;; Faces (defface which-key-key-face '((t . (:inherit font-lock-constant-face))) @@ -277,6 +284,8 @@ to a non-nil value for the execution of a command. Like this Used when `which-key-popup-type' is frame.") (defvar which-key--echo-keystrokes-backup nil "Internal: Backup the initial value of `echo-keystrokes'.") +(defvar which-key--prefix-help-cmd-backup nil + "Internal: Backup the value of `prefix-help-command'.") (defvar which-key--pages-plist nil "Internal: Holds page objects") (defvar which-key--lighter-backup nil @@ -302,12 +311,17 @@ Used when `which-key-popup-type' is frame.") (if which-key-mode (progn (unless which-key--is-setup (which-key--setup)) + (when which-key-use-C-h-for-paging + (setq which-key--prefix-help-cmd-backup prefix-help-command + prefix-help-command #'which-key-show-next-page)) (add-hook 'pre-command-hook #'which-key--hide-popup) (add-hook 'pre-command-hook #'which-key--lighter-restore) (add-hook 'focus-out-hook #'which-key--stop-timer) (add-hook 'focus-in-hook #'which-key--start-timer) (which-key--start-timer)) (setq echo-keystrokes which-key--echo-keystrokes-backup) + (when which-key-use-C-h-for-paging + (setq prefix-help-command which-key--prefix-help-cmd-backup)) (remove-hook 'pre-command-hook #'which-key--hide-popup) (remove-hook 'pre-command-hook #'which-key--lighter-restore) (remove-hook 'focus-out-hook #'which-key--stop-timer) @@ -382,7 +396,6 @@ bottom." (setq which-key-popup-type 'minibuffer which-key-show-prefix 'left)) - ;; Helper functions to modify replacement lists. (defun which-key--add-key-based-replacements (alist key repl) @@ -974,16 +987,22 @@ enough space based on your settings and frame size." prefix-keys) (string-width status-left)))) (prefix-left (s-pad-right first-col-width " " prefix-w-face)) (status-left (s-pad-right first-col-width " " status-left)) - (nxt-pg-hint (when (and (< 1 n-pages) - (eq 'which-key-show-next-page - (key-binding - (kbd (concat prefix-keys - " " - which-key-paging-key))))) - (propertize (format "[%s pg %s]" - which-key-paging-key - (1+ (mod (1+ page-n) n-pages))) - 'face 'which-key-note-face))) + (nxt-pg-hint (cond ((and (< 1 n-pages) + which-key-use-C-h-for-paging) + (propertize (format "[C-h pg %s]" + (1+ (mod (1+ page-n) n-pages))) + 'face 'which-key-note-face)) + ((and (< 1 n-pages) + (eq 'which-key-show-next-page + (key-binding + (kbd (concat prefix-keys + " " + which-key-paging-key))))) + (propertize (format "[%s pg %s]" + which-key-paging-key + (1+ (mod (1+ page-n) n-pages))) + 'face 'which-key-note-face)) + (t nil))) new-end lines first) (cond ((and (< 1 n-pages) (eq which-key-show-prefix 'left)) @@ -1029,6 +1048,16 @@ enough space based on your settings and frame size." prefix-keys) (which-key--show-page next-page)) (which-key--start-paging-timer))) + +;; (defun which-key-show-first-page () +;; "Show the first page of keys." +;; ;; (which-key--stop-timer) +;; ;; (setq which-key--prefix-help-cmd-backup prefix-help-command +;; ;; prefix-help-command 'which-key-show-next-page) +;; (which-key--show-page 0) +;; ) +;; ;; (which-key--start-paging-timer)) + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; Update @@ -1064,21 +1093,20 @@ Finally, show the buffer." ;; just in case someone uses one of these (keymapp (lookup-key function-key-map prefix-keys))) (not which-key-inhibit)) - (let ((page-n 0)) - (setq which-key--current-prefix prefix-keys - which-key--last-try-2-loc nil) - (let ((formatted-keys (which-key--get-formatted-key-bindings - (current-buffer))) - (prefix-keys-desc (key-description prefix-keys))) - (cond ((= (length formatted-keys) 0) - (message "%s- which-key: There are no keys to show" prefix-keys-desc)) - ((listp which-key-side-window-location) - (setq which-key--last-try-2-loc - (apply #'which-key--try-2-side-windows - formatted-keys page-n which-key-side-window-location))) - (t (setq which-key--pages-plist - (which-key--create-pages formatted-keys (window-width))) - (which-key--show-page page-n)))))))) + (setq which-key--current-prefix prefix-keys + which-key--last-try-2-loc nil) + (let ((formatted-keys (which-key--get-formatted-key-bindings + (current-buffer))) + (prefix-keys-desc (key-description prefix-keys))) + (cond ((= (length formatted-keys) 0) + (message "%s- which-key: There are no keys to show" prefix-keys-desc)) + ((listp which-key-side-window-location) + (setq which-key--last-try-2-loc + (apply #'which-key--try-2-side-windows + formatted-keys 0 which-key-side-window-location))) + (t (setq which-key--pages-plist + (which-key--create-pages formatted-keys (window-width))) + (which-key--show-page 0))))))) ;; Timers @@ -1102,6 +1130,7 @@ Finally, show the buffer." (and (< 0 (length (this-single-command-keys))) (not (equal which-key--current-prefix (this-single-command-keys))))) + (setq which-key--current-page-n nil) (cancel-timer which-key--paging-timer) (which-key--start-timer)))))) -- 2.30.2